#include "../include/routemap.h"
#include "../include/route.h"
#include <limits.h>
using namespace std;
using namespace Glib;
using namespace Gio;

namespace vectorMap{

double Place::lengthSquare(Place* to){
    double xdif =ABSDIF(x, to->x);
    double ydif =ABSDIF(y, to->y);
    return xdif*xdif + ydif*ydif;
}

double Path::lengthSquare(){
	if (!from || !to)
		return INT_MAX;
	return from->place->lengthSquare(to->place);
}




RouteMap::RouteMap()
{
    left=INT_MAX;
    right=INT_MIN;
    top=INT_MAX;
    bottom=INT_MIN;
    //ctor
}

RouteMap::~RouteMap()
{
    //dtor
}

void RouteMap::finalize(){
	
	const int nodecount = nodes.size();
	//fill the map with "infinite" numbers
	FWmap = new int*[nodecount];
	FWnextMap = new int*[nodecount];
	for (int i=0; i<nodecount; i++)
	{
		FWmap[i]= new int[nodecount];
		FWnextMap[i]= new int[nodecount];
		for (int j=0; j<nodecount; j++){
			FWmap[i][j]=INT_MAX;
			FWnextMap[i][j]=-1;
		}
		//fill in the known (direct) connections
		for(auto iter=nodes[i].outgoing.begin(); iter<nodes[i].outgoing.end(); iter++)
		{
			int to = getNodeIndex((*iter)->to);
			int len= (*iter)->length();
			FWmap[i][to] = len;
			FWnextMap[i][to] = to;
		}
	}
	// now, for the real floyd-warshalling part
	
	for (int split=0; split<nodecount; split++)
	for (int     i=0;     i<nodecount;     i++)
	for (int     j=0;     j<nodecount;     j++)
	{
			if(FWmap [i][split]==INT_MAX||FWmap[split][j]==INT_MAX)
				continue;
			if( FWmap[i][split] + FWmap[split][j] < FWmap[i][j]){
				FWmap[i][j]= FWmap [i][split]+ FWmap[split][j];
				FWnextMap[i][j]    =FWnextMap[i][split]; 
			}
	}
	finalized=true;
}
void RouteMap::invalidate()
{
   left=INT_MAX;
    right=INT_MIN;
    top=INT_MAX;
    bottom=INT_MIN;
	nodes.clear();
	filled=false;
	finalized=false;
	m_signal_invalidate.emit();
 }

sigc::signal<bool> RouteMap::signal_invalidate()
{
	return m_signal_invalidate;
}


int RouteMap::getNodeIndex(Node* node)
{
if(node < &*nodes.begin() || node >=&*nodes.end())
	return -1;
return node - &*nodes.begin();
}
Route* RouteMap::route(int fromIndex, int toIndex)
{
	int count=10000;//maximum of 1000 nodes
	Route* result = new Route(&nodes[fromIndex]);
	while(fromIndex!=toIndex ){
		if(!count--||fromIndex<0 || fromIndex>=nodes.size()){
			cout << "wrong index:" << fromIndex << endl;
			return 0;
		}
		fromIndex=FWnextMap[fromIndex][toIndex];
		*result << &nodes[fromIndex];
	}
	return result;
}

}
